﻿#region Using Directives

    using System;  

    using Csla;

    using MarketPulse.BusinessLogic.Core;
using MarketPulse.BusinessLogic.Common.Criteria;

#endregion

namespace MarketPulse.BusinessLogic.Private
{
    /// <summary>
    /// This class represents a branch. A branch is an actual client site that will be visited/reported on as part of a particular component or program. A branch has several important children that
    /// affect how and when the branch is interacted with in the context of a visit.
    /// Branch Status - A collection of time based status used to view the status of a branch for any upcoming (scheduled) visits.
    /// Branch Attributes - A collection of attributes used to describe the branch in greater detail.    
    /// 
    /// A branch belongs to a client (Company of a specific type) and is the physical destination for a visit. 
    /// </summary>
    [Serializable]
    [Csla.Server.ObjectFactory("MarketPulse.DataAccess.Factory.BranchFactory, MarketPulse.DataAccess.Factory")]
    public class Branch : MarketPulseBase<Branch>
    {
        #region Constructors

            /// <summary>
            /// Default constructor for this class, marked as private in order to (try to) enforce construction
            /// only via the static factory methods provided.
            /// </summary>
            private Branch()
            {
            }

        #endregion

        #region Methods

            #region Factory Methods

                /// <summary>
                /// Method used to create a new Branch object (via the DataPortal client proxy)
                /// </summary>
                /// <returns>The newly created Branch object</returns>
                public static Branch New()
                {
                    return DataPortal.Create<Branch>();
                }

                /// <summary>
                /// Method used to retrieve an existing Branch object from the database using the provided Guid (via the DataPortal client proxy)
                /// </summary>
                /// <param name="guid">The Guid of the Branch to retrieve</param>
                /// <returns>A valid (filled) Branch object from the database</returns>
                public static Branch Get(Guid guid)
                {
                    return DataPortal.Fetch<Branch>(new SingleCriteria<Guid>(guid));
                }

                /// <summary>
                /// Method used to update the supplied Branch object (via the DataPortal client proxy)
                /// </summary>
                /// <param name="branch">The Branch object to update</param>
                /// <returns>A Branch object that represents the Round after the update</returns>
                public static Branch Update(Branch branch)
                {
                    return DataPortal.Update<Branch>(branch);
                }

            #endregion

            #region Business Process Methods

                /// <summary>
                /// Method used to add a BranchAttribute to a Branch
                /// </summary>
                /// <param name="branchAttributeType">The type guid of the type of attribute to add</param>
                public void AddBranchAttribute(Guid branchAttributeType)
                {
                    BranchAttribute attribute = BranchAttribute.New();
                    attribute.BranchAttributeTypeGUID = branchAttributeType;
                    attribute.BranchGUID = this.GUID;

                    Attributes.Add(attribute);
                }

            #endregion

        #endregion

        #region Properties

            #region Association GUID Properties (Foreign Keys)

                /// <summary>
                /// The GUID of the company (BusinessObject) that this Branch belongs to 
                /// </summary>
                public static PropertyInfo<Nullable<Guid>> CompanyGUIDProperty = RegisterProperty<Nullable<Guid>>(p => p.CompanyGUID);
                /// <summary>
                /// The GUID of the company (BusinessObject) that this Branch belongs to 
                /// </summary>
                public Nullable<Guid> CompanyGUID
                {
                    get { return GetProperty(CompanyGUIDProperty); }
                    set { SetProperty(CompanyGUIDProperty, value); }
                }

                /// <summary>
                /// The GUID of the area (BusinessObject) that this Branch is in
                /// </summary>
                public static PropertyInfo<Nullable<Guid>> AreaGUIDProperty = RegisterProperty<Nullable<Guid>>(p => p.AreaGUID);
                /// <summary>
                /// The GUID of the area (BusinessObject) that this Branch is in
                /// </summary>
                public Nullable<Guid> AreaGUID
                {
                    get { return GetProperty(AreaGUIDProperty); }
                    set { SetProperty(AreaGUIDProperty, value); }
                }

                /// <summary>
                /// The corresponding Legacy ID for this branch (from legacy database)
                /// </summary>
                public static PropertyInfo<long> LegacyBranchIDProperty = RegisterProperty<long>(p => p.LegacyBranchID);
                /// <summary>
                /// The corresponding Legacy ID for this branch (from legacy database)
                /// </summary>
                public long LegacyBranchID
                {
                    get { return GetProperty(LegacyBranchIDProperty); }
                    set { SetProperty(LegacyBranchIDProperty, value); }
                }

            #endregion

            /// <summary>
            /// A human readable name for this Branch
            /// </summary>
            public static PropertyInfo<string> BranchNameProperty = RegisterProperty<string>(p => p.Name);
            /// <summary>
            /// A human readable name for this Branch
            /// </summary>
            public string Name
            {
                get { return GetProperty(BranchNameProperty); }
                set { SetProperty(BranchNameProperty, value); }
            }

            /// <summary>
            /// A human readable Building name or number
            /// </summary>
            public static PropertyInfo<string> BuildingNameOrNumberProperty = RegisterProperty<string>(p => p.BuildingNameOrNumber);
            /// <summary>
            /// A human readable Building name or number
            /// </summary>
            public string BuildingNameOrNumber
            {
                get { return GetProperty(BuildingNameOrNumberProperty); }
                set { SetProperty(BuildingNameOrNumberProperty, value); }
            }

            /// <summary>
            /// A human readable Address line (number 1 of 5)
            /// </summary>
            public static PropertyInfo<string> AddressLine1Property = RegisterProperty<string>(p => p.AddressLine1);
            /// <summary>
            /// A human readable Address line (number 1 of 5)
            /// </summary>
            public string AddressLine1
            {
                get { return GetProperty(AddressLine1Property); }
                set { SetProperty(AddressLine1Property, value); }
            }

            /// <summary>
            /// A human readable Address line (number 2 of 5)
            /// </summary>
            public static PropertyInfo<string> AddressLine2Property = RegisterProperty<string>(p => p.AddressLine2);
            /// <summary>
            /// A human readable Address line (number 2 of 5)
            /// </summary>
            public string AddressLine2
            {
                get { return GetProperty(AddressLine2Property); }
                set { SetProperty(AddressLine2Property, value); }
            }

            /// <summary>
            /// A human readable Address line (number 3 of 5)
            /// </summary>
            public static PropertyInfo<string> AddressLine3Property = RegisterProperty<string>(p => p.AddressLine3);
            /// <summary>
            /// A human readable Address line (number 3 of 5)
            /// </summary>
            public string AddressLine3
            {
                get { return GetProperty(AddressLine3Property); }
                set { SetProperty(AddressLine3Property, value); }
            }

            /// <summary>
            /// A human readable Address line (number 4 of 5)
            /// </summary>
            public static PropertyInfo<string> AddressLine4Property = RegisterProperty<string>(p => p.AddressLine4);
            /// <summary>
            /// A human readable Address line (number 4 of 5)
            /// </summary>
            public string AddressLine4
            {
                get { return GetProperty(AddressLine4Property); }
                set { SetProperty(AddressLine4Property, value); }
            }

            /// <summary>
            /// A human readable Address line (number 5 of 5)
            /// </summary>
            public static PropertyInfo<string> AddressLine5Property = RegisterProperty<string>(p => p.AddressLine5);
            /// <summary>
            /// A human readable Address line (number 5 of 5)
            /// </summary>
            public string AddressLine5
            {
                get { return GetProperty(AddressLine5Property); }
                set { SetProperty(AddressLine5Property, value); }
            }   

            /// <summary>
            /// A human readable Postal Code
            /// </summary>
            public static PropertyInfo<string> PostCodeProperty = RegisterProperty<string>(p => p.PostCode);
            /// <summary>
            /// A human readable Postal Code
            /// </summary>
            public string PostCode
            {
                get { return GetProperty(PostCodeProperty); }
                set { SetProperty(PostCodeProperty, value); }
            }

            /// <summary>
            /// A general memo field
            /// </summary>
            public static PropertyInfo<string> MemoProperty = RegisterProperty<string>(p => p.Memo);
            /// <summary>
            /// A general memo field
            /// </summary>
            public string Memo
            {
                get { return GetProperty(MemoProperty); }
                set { SetProperty(MemoProperty, value); }
            }

            /// <summary>
            /// The latitude position of this Branch
            /// </summary>
            public static PropertyInfo<double> LatitudeProperty = RegisterProperty<double>(p => p.Latitude);
            /// <summary>
            /// The latitude position of this Branch
            /// </summary>
            public double Latitude
            {
                get { return GetProperty(LatitudeProperty); }
                set { SetProperty(LatitudeProperty, value); }
            }

            /// <summary>
            /// The longtitude position of this Branch
            /// </summary>
            public static PropertyInfo<double> LongtitudeProperty = RegisterProperty<double>(p => p.Longtitude);
            /// <summary>
            /// The longtitude position of this Branch
            /// </summary>
            public double Longtitude
            {
                get { return GetProperty(LongtitudeProperty); }
                set { SetProperty(LongtitudeProperty, value); }
            }

            #region Association Properties (Related Objects)

                /// <summary>
                /// A collection of branch attributes associaetd with the Branch
                /// </summary>
                public static PropertyInfo<BranchAttributeList> BranchAttributeListProperty = RegisterProperty<BranchAttributeList>(p => p.Attributes);
                /// <summary>
                /// A collection of branch attributes associaetd with the Branch
                /// </summary>
                public BranchAttributeList Attributes
                {
                    get
                    {
                        // If the property hasn't been loaded yet
                        if (!FieldManager.FieldExists(BranchAttributeListProperty))
                        {
                            if (IsNew)
                            {
                                // Load the property and notify CSLA that the property has changed
                                LoadProperty(BranchAttributeListProperty, BranchAttributeList.New());
                                OnPropertyChanged(BranchAttributeListProperty);
                            }
                            else
                            {
                                // Load the property
                                LoadProperty(BranchAttributeListProperty, BranchAttributeList.Get(GUID.Value));
                            }
                            return ReadProperty(BranchAttributeListProperty);
                        }
                        else
                        {
                            // Return the current property
                            return GetProperty(BranchAttributeListProperty);
                        }
                    }
                } 

            #endregion

        #endregion

    }
}
